---
title: 'Astro DB'
description: Astro 전용으로 설계된 완전 관리형 SQL 데이터베이스인 Astro DB를 사용하는 방법을 알아보세요.
githubIntegrationURL: 'https://github.com/withastro/astro/tree/main/packages/db/'
i18nReady: true
---
import { FileTree } from '@astrojs/starlight/components';
import PackageManagerTabs from '~/components/tabs/PackageManagerTabs.astro';
import ReadMore from '~/components/ReadMore.astro';
import Since from '~/components/Since.astro';
import { Steps } from '@astrojs/starlight/components';

Astro DB는 Astro 생태계를 위해 설계된 완전 관리형 SQL 데이터베이스입니다. Astro에서 로컬로 개발하여 모든 libSQL 호환 데이터베이스에 배포하세요.

Astro DB는 데이터를 구성, 개발, 쿼리할 수 있는 완벽한 솔루션입니다. Docker나 네트워크 연결 없이도 데이터를 관리하기 위해 `astro dev`를 실행할 때마다 로컬 데이터베이스가 `.astro/content.db`에 생성됩니다.

## 설치

내장된 `astro add` 명령을 사용하여 [`@astrojs/db` 통합](/ko/guides/integrations-guide/db/)을 설치합니다:

<PackageManagerTabs>
  <Fragment slot="npm">
  ```sh
  npx astro add db
  ```
  </Fragment>
  <Fragment slot="pnpm">
  ```sh
  pnpm astro add db
  ```
  </Fragment>
  <Fragment slot="yarn">
  ```sh
  yarn astro add db
  ```
  </Fragment>
</PackageManagerTabs>

## 데이터베이스 정의

`astro add` 명령으로 `@astrojs/db`를 설치하면 프로젝트에 데이터베이스 테이블을 정의할 `db/config.ts` 파일이 자동으로 생성됩니다:

```ts title="db/config.ts"
import { defineDb } from 'astro:db';

export default defineDb({
  tables: { },
})
```

### 테이블

Astro DB의 데이터는 SQL 테이블을 사용하여 저장됩니다. 테이블은 데이터를 행과 열로 구조화하며, 여기서 열은 각 행 값의 타입을 적용합니다.

기존 libSQL 데이터베이스의 데이터 구조 또는 새 데이터베이스에서 수집할 데이터를 제공하여 `db/config.ts` 파일에 테이블을 정의하세요. 이렇게 하면 Astro가 프로젝트에서 해당 테이블을 쿼리하기 위한 TypeScript 인터페이스를 생성할 수 있습니다. 결과적으로 데이터에 액세스할 때 속성 자동 완성 및 타입 검사를 통해 완전한 TypeScript 지원이 제공됩니다.

데이터베이스 테이블을 구성하려면 `astro:db`에서 `defineTable()` 및 `column` 유틸리티를 가져와 사용하세요. 그런 다음 테이블의 이름 (대소문자 구분)과 각 열의 데이터 타입을 정의합니다.

이 예시에서는 `author` 및 `body`에 대한 필수 텍스트 열이 있는 `Comment` 테이블을 구성합니다. 그런 다음 `defineDb()` 내보내기를 통해 프로젝트에서 사용할 수 있도록 합니다.

```ts title="db/config.ts" "Comment"
import { defineDb, defineTable, column } from 'astro:db';

const Comment = defineTable({
  columns: {
    author: column.text(),
    body: column.text(),
  }
})

export default defineDb({
  tables: { Comment },
})
```

<ReadMore>테이블 옵션에 대한 전체 참조는 [테이블 구성 참조](/ko/guides/integrations-guide/db/#테이블-구성-참조)를 확인하세요.</ReadMore>

### 열 (Columns)

Astro DB는 다음 열 타입을 지원합니다.

```ts title="db/config.ts" "column.text()" "column.number()" "column.boolean()" "column.date()" "column.json()"
import { defineTable, column } from 'astro:db';

const Comment = defineTable({
  columns: {
    // 텍스트 문자열입니다.
    author: column.text(),
    // 정수 값입니다.
    likes: column.number(),
    // 참 또는 거짓 값입니다.
    flagged: column.boolean(),
    // JavaScript Date 객체로 쿼리되는 날짜/시간 값입니다.
    published: column.date(),
    // 타입이 설정되지 않은 JSON 객체입니다.
    metadata: column.json(),
  }
});
```

<ReadMore>자세한 내용은 [테이블 열 참조](/ko/guides/integrations-guide/db/#테이블-구성-참조)를 확인하세요.</ReadMore>

### 테이블 참조

테이블 간 관계는 데이터베이스 디자인의 일반적인 패턴입니다. 예를 들어, `Blog` 테이블은 `Comment`, `Author` 및 `Category`의 다른 테이블과 밀접하게 관련될 수 있습니다.

테이블 간 관계를 정의하고 **참조 열 (reference columns)** 을 사용하여 데이터베이스 스키마에 저장할 수 있습니다. 관계를 구축하려면 다음이 필요합니다.

- 참조 테이블의 **식별자 열 (identifier column)** 이 필요합니다. 이는 일반적으로 `primaryKey` 속성이 있는 `id` 열입니다.
- **참조된 `id`를 저장하기 위한 기본 테이블의 열** 이 필요합니다. 이는 관계를 설정하기 위해 `references` 속성을 사용합니다.

이 예시에서는 `Author` 테이블의 `id` 열을 참조하는 `Comment` 테이블의 `authorId` 열을 보여줍니다.

```ts title="db/config.ts" {3, 10}
const Author = defineTable({
  columns: {
    id: column.number({ primaryKey: true }),
    name: column.text(),
  }
});

const Comment = defineTable({
  columns: {
    authorId: column.number({ references: () => Author.columns.id }),
    body: column.text(),
  }
});
```

## 개발 모드에서 데이터베이스 시드

개발 모드에서 Astro는 DB 구성을 사용하여 스키마에 따라 로컬 타입을 생성합니다. 이는 개발 서버가 시작될 때마다 시드 파일에서 새로 생성되며 타입 안전성 및 자동 완성을 통해 데이터 형태를 쿼리하고 작업할 수 있습니다.

개발 모드에서 [원격 데이터베이스에 연결](#원격-데이터베이스에-연결)하지 않으면 개발 중에 프로덕션 데이터에 액세스할 수 없습니다. 이렇게 하면 데이터를 보호하는 동시에 타입 안전성이 보장된 작동 중인 데이터베이스로 테스트하고 개발할 수 있습니다.

테스트 및 디버깅을 위해 개발 데이터를 Astro 프로젝트에 시드하려면 `db/seed.ts` 파일을 생성합니다. `db` 객체와 `astro:db`에 정의된 테이블을 모두 가져옵니다. 각 테이블에 초기 데이터를 `insert` 합니다. 이 개발 데이터는 데이터베이스 스키마 및 프로덕션 데이터의 형식과 일치해야 합니다.

다음 예시에서는 `Comment` 테이블과 `Author` 테이블에 대한 개발 데이터의 두 행을 정의합니다.

```ts title="db/seed.ts"
import { db, Comment, Author } from 'astro:db';

export default async function() {
  await db.insert(Author).values([
    { id: 1, name: "Kasim" },
    { id: 2, name: "Mina" },
  ]);

  await db.insert(Comment).values([
    { authorId: 1, body: 'Hope you like Astro DB!' },
    { authorId: 2, body: 'Enjoy!'},
  ])
}
```

개발 서버는 이 파일이 변경될 때마다 자동으로 데이터베이스를 다시 시작하여 타입을 재생성하고 매번 `seed.ts`에서 이 개발 데이터를 새로 시드합니다.

## 프로덕션용 libSQL 데이터베이스 연결

Astro DB는 관리형 또는 자체 호스팅에 관계없이 모든 로컬 libSQL 데이터베이스 또는 libSQL 원격 프로토콜을 노출하는 모든 서버에 연결할 수 있습니다.

Astro DB를 libSQL 데이터베이스에 연결하려면 데이터베이스 제공업체에서 얻은 다음 환경 변수를 설정하세요:

- `ASTRO_DB_REMOTE_URL`: 로컬 또는 원격 libSQL DB의 위치에 대한 연결 URL입니다. 여기에는 동기화 및 암호화와 같은 [URL 구성 옵션](#원격-url-구성-옵션)이 매개변수로 포함될 수 있습니다.
- `ASTRO_DB_APP_TOKEN`: libSQL 서버의 인증 토큰입니다. 이는 원격 데이터베이스에 필요하며 [파일 또는 인메모리와 같은 로컬 DB](#url-스킴-및-호스트) 데이터베이스에는 필요하지 않습니다.

서비스에 따라 CLI 또는 웹 UI에 액세스하여 이러한 값을 검색할 수 있습니다. 다음 섹션에서는 Turso에 연결하여 이러한 값을 설정하는 방법을 예시로 보여드리지만, 어떤 제공업체를 사용하든 자유롭게 사용할 수 있습니다.

### Turso로 시작하기

Turso는 Astro DB를 구동하는 SQLite의 오픈 소스 포크인 [libSQL](https://github.com/tursodatabase/libsql)을 개발한 회사입니다. 완전히 관리되는 libSQL 데이터베이스 플랫폼을 제공하며 Astro와 완벽하게 호환됩니다.

아래 단계는 Turso CLI 설치, 로그인 (또는 가입), 새 데이터베이스 생성, 필요한 환경 변수 가져오기, 스키마를 원격 데이터베이스에 푸시하는 과정을 안내합니다.

<Steps>

1. [Turso CLI](https://docs.turso.tech/cli/installation)를 설치합니다.

2. Turso에 [로그인 또는 가입](https://docs.turso.tech/cli/authentication)합니다.

3. 새 데이터베이스를 생성합니다. 이 예시에서 데이터베이스 이름은 `andromeda`입니다.

    ```sh "andromeda"
    turso db create andromeda
    ```

4. `show` 명령을 실행하여 새로 생성된 데이터베이스에 대한 정보를 확인합니다:

    ```sh "andromeda"
    turso db show andromeda
    ```

    `URL` 값을 복사하여 `ASTRO_DB_REMOTE_URL`의 값으로 설정합니다.


    ```dotenv title=".env" "libsql://andromeda-houston.turso.io"
    ASTRO_DB_REMOTE_URL=libsql://andromeda-houston.turso.io
    ```

5. 데이터베이스에 대한 요청을 인증할 새 토큰을 생성합니다:

    ```sh "andromeda"
    turso db tokens create andromeda
    ```

    명령의 출력을 복사하여 `ASTRO_DB_APP_TOKEN`의 값으로 설정합니다.

    ```dotenv title=".env" add={2} "eyJhbGciOiJF...3ahJpTkKDw"
    ASTRO_DB_REMOTE_URL=libsql://andromeda-houston.turso.io
    ASTRO_DB_APP_TOKEN=eyJhbGciOiJF...3ahJpTkKDw
    ```

6. DB 스키마 및 메타데이터를 새 Turso 데이터베이스로 푸시합니다.

    ```sh
    astro db push --remote
    ```

7. 축하합니다, 이제 데이터베이스가 연결되었습니다! 이제 휴식을 취하세요. 👾

    ```sh
    turso relax
    ```

</Steps>

Turso의 더 많은 기능을 살펴보려면 [Turso 문서](https://docs.turso.tech)를 확인하세요.

### 원격 데이터베이스에 연결

Astro DB를 사용하면 로컬 및 원격 데이터베이스에 모두 연결할 수 있습니다. 기본적으로 Astro는 `dev` 및 `build` 명령에 로컬 데이터베이스 파일을 사용하여 테이블을 다시 생성하고 매번 개발 시드 데이터를 삽입합니다.

호스팅된 원격 데이터베이스에 연결하려면 `--remote` 플래그를 사용합니다. 이 플래그를 사용하면 원격 데이터베이스에 대한 읽기 및 쓰기 액세스가 모두 가능하므로 프로덕션 환경에서 [사용자 데이터를 허용 및 유지](#insert)할 수 있습니다.

`--remote` 플래그를 사용하도록 빌드 명령을 구성합니다:

```json title="package.json" "--remote"
{
  "scripts": {
    "build": "astro build --remote"
  }
}
```

명령줄에서 직접 플래그를 사용할 수도 있습니다:

```bash
# 원격 연결을 통한 빌드
astro build --remote

# 원격 연결을 통한 개발
astro dev --remote
```

:::caution
개발 모드에서 `--remote`를 사용할 때는 주의하세요. 이렇게 하면 라이브 프로덕션 데이터베이스에 연결되며 모든 변경 사항 (삽입, 업데이트, 삭제)이 유지됩니다.
:::

`--remote` 플래그는 로컬 빌드와 서버에서 모두 원격 DB에 대한 연결을 사용합니다. 로컬 개발 환경과 배포 플랫폼 모두에서 필요한 환경 변수를 설정했는지 확인하세요. 또한 Cloudflare Workers나 Deno와 같은 Node.js가 아닌 런타임 환경에서는 [웹 모드를 구성](/ko/guides/integrations-guide/db/#mode)해야 할 수도 있습니다.

Astro DB 프로젝트를 배포할 때, 배포 플랫폼의 빌드 명령이 `package.json`에 구성된 `--remote` 플래그를 활용하도록 `npm run build` (또는 패키지 관리자에 상응하는 명령어)로 설정되어 있는지 확인하세요.

### 원격 URL 구성 옵션

`ASTRO_DB_REMOTE_URL` 환경 변수는 데이터베이스의 위치와 동기화 및 암호화와 같은 기타 옵션을 구성합니다.

#### URL 스킴 및 호스트

libSQL은 원격 서버의 전송 프로토콜로 HTTP와 WebSockets을 모두 지원합니다. 또한 로컬 파일이나 인메모리 DB 사용도 지원합니다. 이러한 프로토콜은 연결 URL에서 다음 URL 스킴을 사용하여 구성할 수 있습니다:

- `memory:` 인메모리 DB를 사용합니다. 이 경우 호스트는 비어 있어야 합니다.
- `file:` 로컬 파일을 사용합니다. 호스트는 파일 경로입니다 (`file:path/to/file.db`).
- `libsql:` 라이브러리에서 선호하는 프로토콜을 통해 원격 서버를 사용합니다 (버전에 따라 다를 수 있음). 호스트는 서버의 주소 (`libsql://your.server.io`)입니다.
- `http:` HTTP를 통해 원격 서버를 사용합니다. 보안 연결을 사용하려면 `https:`를 사용할 수 있습니다. 호스트는 `libsql:`와 동일합니다.
- `ws:` WebSockets을 통해 원격 서버를 사용합니다. `wss:`를 사용하여 보안 연결을 활성화할 수 있습니다. 호스트는 `libsql:`와 동일합니다.

libSQL 연결의 세부 정보 (예: 암호화 키, 복제, 동기화 간격)는 원격 연결 URL에서 쿼리 매개변수로 구성될 수 있습니다.

예를 들어 암호화된 로컬 파일이 libSQL 서버에 임베디드 복제본으로 작동하도록 하려면 다음 환경 변수를 설정하면 됩니다:

```dotenv title=".env"
ASTRO_DB_REMOTE_URL=file://local-copy.db?encryptionKey=your-encryption-key&syncInterval=60&syncUrl=libsql%3A%2F%2Fyour.server.io
ASTRO_DB_APP_TOKEN=token-to-your-remote-url
```

:::caution
데이터베이스 파일을 사용하는 것은 고급 기능이므로 배포 시 데이터베이스가 재정의되어 프로덕션 데이터가 손실되지 않도록 주의해야 합니다.

또한 서버리스 배포에서는 파일 시스템이 유지되지 않으므로 이 방법은 작동하지 않습니다.
:::

#### `encryptionKey`

libSQL은 암호화된 데이터베이스를 기본적으로 지원합니다. 이 검색 매개변수를 전달하면 지정된 키를 사용하여 암호화를 활성화합니다:

```dotenv title=".env"
ASTRO_DB_REMOTE_URL=file:path/to/file.db?encryptionKey=your-encryption-key
```

#### `syncUrl`

임베디드 복제본은 초고속 읽기를 위해 로컬 파일이나 메모리에 데이터베이스의 전체 동기화 복사본을 저장할 수 있는 libSQL 클라이언트의 기능입니다. 쓰기는 `syncUrl`에 정의된 원격 데이터베이스로 전송되어 로컬 복사본과 동기화됩니다.

이 속성을 사용하여 별도의 연결 URL을 전달하여 데이터베이스를 다른 데이터베이스의 임베디드 복제본으로 전환할 수 있습니다. 이 속성은 `file:` 및 `memory:` 스킴에서만 사용해야 합니다. 매개변수는 URL로 인코딩되어야 합니다.

예를 들어 데이터베이스의 인메모리 임베디드 복제본을 `libsql://your.server.io`에 만들려면 연결 URL을 다음과 같이 설정할 수 있습니다.

```dotenv title=".env"
ASTRO_DB_REMOTE_URL=memory:?syncUrl=libsql%3A%2F%2Fyour.server.io
```

#### `syncInterval`

임베디드 복제본 동기화 간격 (초)입니다. 기본적으로 시작 시와 쓰기 후에만 동기화됩니다.

이 속성은 `syncUrl`도 설정된 경우에만 사용됩니다. 예를 들어 인메모리 임베디드 복제본이 매분 동기화되도록 설정하려면 다음 환경 변수를 설정합니다:

```dotenv title=".env"
ASTRO_DB_REMOTE_URL=memory:?syncUrl=libsql%3A%2F%2Fyour.server.io&syncInterval=60
```

## 데이터베이스 쿼리

제공된 db ORM 및 쿼리 빌더를 사용하여 프로젝트의 모든 [Astro 페이지](/ko/basics/astro-pages/#astro-페이지), [엔드포인트](/ko/guides/endpoints/), 또는 [액션](/ko/guides/actions/)에서 데이터베이스를 쿼리할 수 있습니다.

### Drizzle ORM

```ts
import { db } from 'astro:db';
```

Astro DB에는 [Drizzle ORM](https://orm.drizzle.team/) 클라이언트가 내장되어 있습니다. 클라이언트를 사용하는 데 필요한 설정이나 수동 구성이 없습니다. Astro DB의 `db` 클라이언트는 Astro를 실행할 때 데이터베이스 (로컬 또는 원격)와 통신하도록 자동으로 구성됩니다. 존재하지 않는 열이나 테이블을 참조할 때, TypeScript 오류가 발생한 타입 안정성을 갖춘 SQL 쿼리에 대해 정확한 데이터베이스 스키마 정의를 사용합니다.

### Select

다음 예시에서는 `Comment` 테이블의 모든 행을 선택합니다. 그러면 페이지 템플릿에서 사용할 수 있는 `db/seed.ts` 파일에서 시드된 개발 데이터의 전체 배열이 반환됩니다.

```astro title="src/pages/index.astro"
---
import { db, Comment } from 'astro:db';

const comments = await db.select().from(Comment);
---

<h2>Comments</h2>

{
  comments.map(({ author, body }) => (
    <article>
      <p>Author: {author}</p>
      <p>{body}</p>
    </article>
  ))
}
```

<ReadMore>전체 개요는 [Drizzle `select()` API 참조](https://orm.drizzle.team/docs/select)를 확인하세요.</ReadMore>

### Insert

양식 요청 처리 및 원격 호스팅 데이터베이스에 데이터 삽입과 같은 사용자 입력을 허용하려면 Astro 프로젝트에 [주문형 렌더링](/ko/guides/on-demand-rendering/)을 구성하고 배포 환경에 [SSR 어댑터를 추가](/ko/guides/on-demand-rendering/#어댑터-추가)하세요.

이 예시에서는 구문 분석된 양식 POST 요청을 기반으로 `Comment` 테이블에 행을 삽입합니다.

```astro
---
// src/pages/index.astro
import { db, Comment } from 'astro:db';

if (Astro.request.method === 'POST') {
  // 양식 데이터 구문 분석
  const formData = await Astro.request.formData();
  const author = formData.get('author');
  const body = formData.get('body');
  if (typeof author === 'string' && typeof body === 'string') {
    // Comment 테이블에 양식 데이터 삽입
    await db.insert(Comment).values({ author, body });
  }
}

// 각 요청에 대해 새로운 comments 목록을 렌더링
const comments = await db.select().from(Comment);
---

<form method="POST" style="display: grid">
	<label for="author">Author</label>
	<input id="author" name="author" />

	<label for="body">Body</label>
	<textarea id="body" name="body"></textarea>

	<button type="submit">Submit</button>
</form>

<!--`comments` 렌더링-->
```

[Astro 액션](/ko/guides/actions/)을 사용하여 Astro DB 테이블에 데이터를 삽입할 수도 있습니다. 다음은 액션을 사용하여 `Comment` 테이블에 행을 삽입하는 예시입니다:

```ts
// src/actions/index.ts
import { db, Comment } from 'astro:db';
import { defineAction } from 'astro:actions';
import { z } from 'astro:schema';

export const server = {
  addComment: defineAction({
    // 액션에는 Zod의 타입 안정성이 포함되어 있으므로
    // 페이지에서 typeof {value} === 'string'인지 확인할 필요가 없습니다.
    input: z.object({
      author: z.string(),
      body: z.string(),
    }),
    handler: async (input) => {
      const updatedComments = await db
        .insert(Comment)
        .values(input)
        .returning(); // 업데이트된 comments를 반환합니다.
      return updatedComments;
    },
  }),
};
```

<ReadMore>

전체 개요는 [Drizzle `insert()` API 참조](https://orm.drizzle.team/docs/insert)를 확인하세요.

</ReadMore>

### Delete

API 엔드포인트에서 데이터베이스를 쿼리할 수도 있습니다. 이 예시에서는 `id` 매개변수를 사용하여 `Comment` 테이블에서 행을 삭제합니다:

```ts
// src/pages/api/comments/[id].ts
import type { APIRoute } from "astro";
import { db, Comment, eq } from 'astro:db';

export const DELETE: APIRoute = async (ctx) => {
  await db.delete(Comment).where(eq(Comment.id, ctx.params.id ));
  return new Response(null, { status: 204 });
}
```

<ReadMore>

전체 개요는 [Drizzle `delete()` API 참조](https://orm.drizzle.team/docs/delete)를 확인하세요.

</ReadMore>

### 필터링

특정 속성으로 테이블 결과를 쿼리하려면 [부분 선택을 위한 Drizzle 옵션](https://orm.drizzle.team/docs/select#partial-select)을 사용하세요. 예를 들어, `select()` 쿼리에 [`.where()` 호출](https://orm.drizzle.team/docs/select#filtering)을 추가하고 원하는 비교를 전달합니다.

다음 예시에서는 "Astro DB"라는 문구가 포함된 `Comment` 테이블의 모든 행을 쿼리합니다. `body`에 문구가 있는지 확인하려면 [`like()` 연산자](https://orm.drizzle.team/docs/operators#like)를 사용하세요.

```astro title="src/pages/index.astro"
---
import { db, Comment, like } from 'astro:db';

const comments = await db.select().from(Comment).where(
    like(Comment.body, '%Astro DB%')
);
---
```

### Drizzle 유틸리티

쿼리 작성을 위한 모든 Drizzle 유틸리티는 `astro:db` 모듈에서 노출됩니다. 여기에는 다음이 포함됩니다.

- [필터 연산자](https://orm.drizzle.team/docs/operators) 예: `eq()` 및 `gt()`
- [집계 도우미](https://orm.drizzle.team/docs/select#aggregations-helpers) 예: `count()`
- [`sql` 도우미](https://orm.drizzle.team/docs/sql) - 원시 SQL 쿼리 작성

```ts
import { eq, gt, count, sql } from 'astro:db';
```

### 관계

SQL join을 사용하여 여러 테이블에서 관련 데이터를 쿼리할 수 있습니다. join 쿼리를 생성하려면 `db.select()` 문을 join 연산자로 확장하세요. 각 함수는 join할 테이블과 두 테이블 사이의 행을 일치시키는 조건을 인자로 전달받습니다.

이 예시에서는 `innerJoin()` 함수를 사용하여 `authorId` 열을 기반으로 `Comment`의 authors를 관련 `Author` 정보와 join합니다. 그러면 각 `Author` 및 `Comment` 행이 최상위 속성인 객체 배열이 반환됩니다.

```astro title="src/pages/index.astro"
---
import { db, eq, Comment, Author } from 'astro:db';

const comments = await db.select()
  .from(Comment)
  .innerJoin(Author, eq(Comment.authorId, Author.id));
---

<h2>Comments</h2>

{
  comments.map(({ Author, Comment }) => (
    <article>
      <p>Author: {Author.name}</p>
      <p>{Comment.body}</p>
    </article>
  ))
}
```

<ReadMore>

사용 가능한 모든 join 연산자 및 구성 옵션은 [Drizzle join 참조](https://orm.drizzle.team/docs/joins#join-types)를 확인하세요.

</ReadMore>

### 일괄 트랜잭션

모든 원격 데이터베이스 쿼리는 네트워크 요청으로 이루어집니다. 많은 수의 쿼리를 수행할 때 쿼리를 단일 트랜잭션으로 함께 "일괄 처리"하거나 쿼리가 실패할 경우 자동 롤백을 수행해야 할 수도 있습니다.

이 예시에서는 `db.batch()` 메서드를 사용하여 단일 요청에 여러 행을 시드합니다.

```ts
// db/seed.ts
import { db, Author, Comment } from 'astro:db';

export default async function () {
  const queries = [];
  // 단일 네트워크 요청으로 원격 데이터베이스에 100개의 샘플 comments를 시드합니다.
  for (let i = 0; i < 100; i++) {
    queries.push(db.insert(Comment).values({ body: `Test comment ${i}` }));
  }
  await db.batch(queries);
}
```

<ReadMore>

자세한 내용은 [Drizzle `db.batch()`](https://orm.drizzle.team/docs/batch-api) 문서를 참조하세요.

</ReadMore>

## 데이터베이스에 변경 사항 푸시하기

개발 중에 변경한 내용을 데이터베이스에 푸시할 수 있습니다.

### 테이블 스키마 푸시

프로젝트가 성장하면서 테이블 스키마는 시간이 지남에 따라 변경될 수 있습니다. 구성 변경 사항을 로컬에서 안전하게 테스트하고 배포할 때 원격 데이터베이스로 푸시할 수 있습니다.

`astro db push --remote` 명령을 사용하여 CLI를 통해 로컬 스키마 변경 사항을 원격 데이터베이스로 푸시할 수도 있습니다.

<PackageManagerTabs>
  <Fragment slot="npm">
  ```sh
  npm run astro db push --remote
  ```
  </Fragment>
  <Fragment slot="pnpm">
  ```sh
  pnpm astro db push --remote
  ```
  </Fragment>
  <Fragment slot="yarn">
  ```sh
  yarn astro db push --remote
  ```
  </Fragment>
</PackageManagerTabs>

이 명령은 데이터 손실 없이 로컬 변경이 이루어질 수 있는지 확인하고 필요한 경우 충돌을 해결하기 위해 스키마를 안전하게 변경하는 방법을 제안합니다.

#### 주요 스키마 변경 사항 푸시

:::caution
__이렇게 하면 데이터베이스가 파괴됩니다__. 프로덕션 데이터가 필요하지 않은 경우에만 이 명령을 수행하세요.
:::

원격 데이터베이스에서 호스팅되는 기존 데이터와 호환되지 않는 방식으로 테이블 스키마를 변경해야 하는 경우 프로덕션 데이터베이스를 초기화해야 합니다.

주요 변경 사항이 포함된 테이블 스키마 업데이트를 푸시하려면 `--force-reset` 플래그를 추가하여 모든 프로덕션 데이터를 초기화하세요.

<PackageManagerTabs>
  <Fragment slot="npm">
  ```sh
  npm run astro db push --remote --force-reset
  ```
  </Fragment>
  <Fragment slot="pnpm">
  ```sh
  pnpm astro db push --remote --force-reset
  ```
  </Fragment>
  <Fragment slot="yarn">
  ```sh
  yarn astro db push --remote --force-reset
  ```
  </Fragment>
</PackageManagerTabs>

### 테이블 이름 변경

스키마를 원격 데이터베이스로 푸시한 후 테이블 이름을 변경할 수 있습니다.

**중요한 프로덕션 데이터가 없는** 경우 `--force-reset` 플래그를 사용하여 [데이터베이스를 초기화](#주요-스키마-변경-사항-푸시)할 수 있습니다. 이 플래그는 데이터베이스의 모든 테이블을 삭제하고 현재 스키마와 정확히 일치하는 새 테이블을 생성합니다.

프로덕션 데이터를 보존하면서 테이블 이름을 변경하려면, 기존 기능을 중단하지 않는 변경을 수행하여 로컬 스키마를 원격 데이터베이스에 안전하게 푸시해야 합니다.

다음 예시에서는 테이블의 이름을 `Comment`에서 `Feedback`으로 변경합니다.

<Steps>

1. 데이터베이스 구성 파일에서 이름을 바꾸려는 테이블에 `deprecated: true` 속성을 추가하세요.

    ```ts title="db/config.ts" ins={2}
    const Comment = defineTable({
      deprecated: true,
    	columns: {
    		author: column.text(),
    		body: column.text(),
  		}
    });
    ```

2. 새 이름으로 새 테이블 스키마 (기존 테이블의 속성과 정확히 일치)를 추가합니다.

	  ```ts title="db/config.ts" ins={8-14}
    const Comment = defineTable({
        deprecated: true,
    	columns: {
    		author: column.text(),
    		body: column.text(),
  		}
    });
	  const Feedback = defineTable({
        columns: {
          author: column.text(),
          body: column.text(),
        }
    });
    ```

3. `astro db push --remote` 명령을 사용하여 [원격 데이터베이스로 푸시](#테이블-스키마-푸시)합니다. 그러면 새 테이블이 추가되고 이전 테이블은 더 이상 사용되지 않는 것으로 표시됩니다.
4. 이전 테이블 대신 새 테이블을 사용하도록 로컬 프로젝트 코드를 업데이트하세요. 데이터를 새 테이블로 마이그레이션해야 할 수도 있습니다.
5. 이전 테이블이 프로젝트에서 더 이상 사용되지 않는다고 확신하면 `config.ts` 파일에서 스키마를 제거할 수 있습니다.
		```ts title="db/config.ts" del={1-7}
    const Comment = defineTable({
          deprecated: true,
    	  columns: {
    		  author: column.text(),
    		  body: column.text(),
  		  }
    });

	  const Feedback = defineTable({
          columns: {
            author: column.text(),
            body: column.text(),
          }
    });
    ```
6. `astro db push --remote` 명령을 사용하여 원격 데이터베이스로 다시 푸시합니다. 이전 테이블은 삭제되고 이름이 변경된 새 테이블만 남습니다.
</Steps>

### 테이블 데이터 푸시

시드 또는 데이터 마이그레이션을 위해 원격 데이터베이스에 데이터를 푸시해야 할 수도 있습니다. 타입 안정성을 갖춘 쿼리를 작성하려면 `astro:db` 모듈을 사용하여 `.ts` 파일을 작성할 수 있습니다. 그런 다음 `astro db execute <file-path> --remote` 명령을 사용하여 원격 데이터베이스에 대해 파일을 실행합니다.

다음 Comments는 `astro db execute db/seed.ts --remote` 명령을 사용하여 시드할 수 있습니다.

```ts
// db/seed.ts
import { Comment } from 'astro:db';

export default async function () {
  await db.insert(Comment).values([
    { authorId: 1, body: 'Hope you like Astro DB!' },
    { authorId: 2, body: 'Enjoy!' },
  ])
}
```

<ReadMore>

전체 명령 목록은 [CLI 참조](/ko/guides/integrations-guide/db/#astro-db-cli-참조)를 확인하세요.

</ReadMore>

## Astro DB 통합 구축

[Astro 통합](/ko/reference/integrations-reference/)은 추가 Astro DB 테이블 및 시드 데이터를 사용하여 사용자 프로젝트를 확장할 수 있습니다.

추가 Astro DB 구성 및 시드 파일을 등록하려면 `astro:db:setup` 후크에서 `extendDb()` 메서드를 사용하세요.
`defineDbIntegration()` 도우미는 `astro:db:setup` 후크에 대한 TypeScript 지원 및 자동 완성 기능을 제공합니다.

```js {8-13}
// my-integration/index.ts
import { defineDbIntegration } from '@astrojs/db/utils';

export default function MyIntegration() {
  return defineDbIntegration({
    name: 'my-astro-db-powered-integration',
    hooks: {
      'astro:db:setup': ({ extendDb }) => {
        extendDb({
          configEntrypoint: '@astronaut/my-package/config',
          seedEntrypoint: '@astronaut/my-package/seed',
        });
      },
      // 기타 통합 후크...
    },
  });
}
```

통합 [config](#데이터베이스-정의) 및 [seed](#개발-모드에서-데이터베이스-시드) 파일은 해당 사용자 정의 파일과 동일한 형식을 따릅니다.

### 타입 안정성을 갖춘 통합 작업

통합 작업을 하는 동안, Astro에서 생성된 (`astro:db`에서 내보낸) 테이블 타입의 이점을 활용하지 못할 수도 있습니다.
완전한 타입 안정성을 위해 `asDrizzleTable()` 유틸리티를 사용하여 데이터베이스 작업에 사용할 수 있는 테이블 참조 객체를 생성하세요.

예를 들어, 다음 `Pets` 데이터베이스 테이블을 설정하는 통합이 있다고 가정해 보겠습니다.

```js
// my-integration/config.ts
import { defineDb, defineTable, column } from 'astro:db';

export const Pets = defineTable({
  columns: {
    name: column.text(),
    species: column.text(),
  },
});

export default defineDb({ tables: { Pets } });
```

시드 파일은 `Pets`를 가져오고 `asDrizzleTable()`을 사용하여 타입 검사를 통해 테이블에 행을 삽입할 수 있습니다.

```js {2,7} /typeSafePets(?! )/
// my-integration/seed.ts
import { asDrizzleTable } from '@astrojs/db/utils';
import { db } from 'astro:db';
import { Pets } from './config';

export default async function() {
  const typeSafePets = asDrizzleTable('Pets', Pets);

  await db.insert(typeSafePets).values([
    { name: 'Palomita', species: 'cat' },
    { name: 'Pan', species: 'dog' },
  ]);
}
```

`asDrizzleTable('Pets', Pets)`에 의해 반환된 값은 `import { Pets } from 'astro:db'`와 동일하지만, Astro의 타입 생성을 실행할 수 없는 경우에도 사용할 수 있습니다.
데이터베이스에 쿼리하거나 삽입해야 하는 모든 통합 코드에서 이를 사용할 수 있습니다.




## Astro Studio에서 Turso로 마이그레이션

<Steps>

1. [Studio 대시보드](https://studio.astro.build/)에서 마이그레이션하려는 프로젝트로 이동합니다. settings 탭에서 "Export Database" 버튼을 사용해 데이터베이스 덤프를 다운로드합니다.
2. 공식 지침에 따라 [Turso CLI를 설치](https://docs.turso.tech/cli/installation)하고, Turso 계정의 [가입 또는 로그인](https://docs.turso.tech/cli/authentication)을 진행합니다.
3. `turso db create` 명령을 사용하여 Turso에서 새 데이터베이스를 생성합니다.
    ```sh
    turso db create [database-name]
    ```
4. Turso CLI를 사용하여 데이터베이스 URL을 가져와서 환경 변수 `ASTRO_DB_REMOTE_URL`로 사용합니다.
    ```sh
    turso db show [database-name]
    ```
    ```dotenv
    ASTRO_DB_REMOTE_URL=[your-database-url]
    ```
5. 데이터베이스에 액세스할 수 있는 토큰을 생성하고 환경 변수 `ASTRO_DB_APP_TOKEN`으로 사용합니다.
    ```sh
    turso db tokens create [database-name]
    ```
    ```dotenv
    ASTRO_DB_APP_TOKEN=[your-app-token]
    ```
6. DB 스키마와 메타데이터를 새 Turso 데이터베이스로 푸시하세요.
    ```sh
    astro db push --remote
    ```
7. 1단계의 데이터베이스 덤프를 새 Turso DB로 가져옵니다.
    ```sh
    turso db shell [database-name] < ./path/to/dump.sql
    ```
8. 프로젝트가 새 데이터베이스에 연결되었음을 확인했으면 Astro Studio에서 프로젝트를 안전하게 삭제할 수 있습니다.

</Steps>
